using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Reflection;
using System.Xml.Xsl;
using System.IO;
using System.Threading;
using Spike.ContractBuilder;

namespace Spike.TestHarness
{
    public partial class TestCaseResultControl : UserControl
    {
        public event EventHandler OnStatusChange;

        delegate void SetTextCallback(string text);
        private Thread updateThread = null;

        public TestCaseResultControl()
        {
            InitializeComponent();
        }

        private string _testname = "TestResult";

        public string TestName
        {
            get { return _testname; }
            set { _testname = value; }
        }

        private TestCaseResult ResultField = null;

        public TestCaseResult Result
        {
            get { return ResultField; }
            set
            {
                ResultField = value;

                RefreshDisplay();

                ResultField.OnUpdated += new EventHandler(ResultField_OnUpdated);
            }
        }

        void ResultField_OnUpdated(object sender, EventArgs e)
        {
            RefreshDisplay();
        }

        public void RefreshDisplay()
        {
            this.updateThread =
                new Thread(new ThreadStart(this.UpdateProc));

            this.updateThread.Start();

            this.Invalidate();
        }

        private void UpdateProc()
        {
            this.SetTime(ResultField.ElapsedTime + " seconds.");
        }

        public void SetTime(string value)
        {
            if (this.txtTime.InvokeRequired)
            {
                try
                {                
                    SetTextCallback d = new SetTextCallback(SetTime);
                    this.Invoke(d, new object[] { value });
                }
                catch                
                {
                    // TODO: there is defect where if IE is requesting permission to display
                    //       the page; the invoke failes.  Ignore for now.
                    string s = string.Empty;
                }
            }
            else
            {
                switch (ResultField.Status)
                {
                    case TestCaseResult.STATUS.Ready: this.BackColor = Color.Gray;                        
                        break;
                    case TestCaseResult.STATUS.Running: this.BackColor = Color.Yellow;
                        break;
                    case TestCaseResult.STATUS.Faulted: this.BackColor = Color.Red;
                         button1.Enabled = true;
                        break;
                    case TestCaseResult.STATUS.Exception: this.BackColor = Color.Red;
                        button1.Enabled = true;
                        break;
                    case TestCaseResult.STATUS.Completed: this.BackColor = Color.Green;
                        break;
                }

                TabPage page = this.Parent as TabPage;
                if (page != null)
                    page.Text = ResultField.Status.ToString();

                try
                {
                    webResponse.DocumentText = PerformTransform(ResultField.Output);
                }
                catch
                {
                    webResponse.DocumentText = "<HTML>" + ResultField.Output +"</HTML>";
                }

                webResponse.Invalidate();

                this.txtTime.Text = value;                
            }

            
        }

        private static string PerformTransform(string document)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(document);

            Assembly ass = Assembly.GetExecutingAssembly();
            StringWriter sw = new StringWriter();
            using (Stream s = ass.GetManifestResourceStream("Spike.TestHarness.xmlview.xslt"))
            {

                XmlReader reader = XmlReader.Create(s);
                XmlTextWriter writer = new XmlTextWriter(sw);
                XslCompiledTransform xsl = new XslCompiledTransform();
                xsl.Load(reader);

                xsl.Transform(doc, null, writer);
                writer.Close();
            }

            return sw.ToString();
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            using (FaultExceptionDialog dlg = new FaultExceptionDialog())
            {
                dlg.SetException(ResultField.Exception);
                dlg.ShowDialog();
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            RefreshDisplay();
        }

        private void btnSaveOutput_Click(object sender, EventArgs e)
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.AddExtension = true;
            dlg.DefaultExt = "xml";
            dlg.Filter = "Xml|*.xml";
            dlg.FileName = TestName +" "+ DateTime.Now.ToString("yyyyMMdd hhmmss") +  "_out.xml";
            dlg.InitialDirectory = ContractGenerator.Instance.GetTestResultsDirectory();
            dlg.Title = "Save Test Result";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                StreamWriter sw = File.CreateText(dlg.FileName);
                sw.Write(Result.Output);
                sw.Close();
            }
        }
    }
}
